import config, { MockConfig, filePath, responseSchema, dataSchema, bodySchema } from './config'
import { findPath, bodyParse, parse } from './utils'
import { Connect } from 'vite'
import Validator from 'jsonschema'

export default function useMiddleWare(
  opts: MockConfig = {}
): Connect.NextHandleFunction {
  const options = {
    ...config,
    ...opts
  }

  // /^\/api(.+)/
  const pattern = new RegExp(`^${options.pattern}(.+)`)
  // 本地路径 + dir路径
  const dir = process.cwd() + options.dir
  return async function(req, res, next) {
    // 区分文件请求和ajax请求 authorization
    // req.headers.authorization
    if (req.url) {
      // 路径
      const match = pattern.exec(req.url)
      // 请求方式
      const method = req.method ? req.method.toLowerCase() : ''
      // 符合mock路由
      if (match) {
        const [mockpath, query = ''] = match[1].split('?')
        // 真实mock文件地址 维护之前请求方式默认找文件
        const mock = findPath(dir + mockpath) ? findPath(dir + mockpath) : findPath(dir + mockpath + filePath.get(method as string))
        if (mock) {
          // 删除缓存
          delete require.cache[require.resolve(mock.url)]
          // 获取参数
          let body: any
          if (method === 'post' || method === 'put' || method === 'delete') {
            body = await bodyParse(req)
          }
          if (method === 'get') {
            body = parse(query)
          }
          // 获取文件
          require('@babel/register')({
            plugins: ['@babel/plugin-transform-modules-commonjs']
          })
          const file = require(mock.url).default
          const data = typeof file === 'function' ? file(body) : file
          // 校验文件
          const v = new Validator.Validator()
          v.addSchema(dataSchema, '/ResponseData')
          v.addSchema(bodySchema, '/ResponseBody')
          const validation = v.validate(data, responseSchema)
          // Throwing an error
          if (validation && validation.errors && validation.errors.length > 0) {
            console.log(filePath)

            console.log(`************** validation error ************
                          error file: ${filePath}
                          error message: ${validation.errors}`)
          } else {
            res.statusCode = data.statusCode
            res.setHeader('Content-Type', 'application/json;charset=utf-8')
            setTimeout(() => {
              res.end(JSON.stringify(data.body))
            }, 300)
          }
        } else {
          // console.log('************** 找不到文件 ************')
          next()
        }
      } else {
        next()
      }
    } else {
      next()
    }
  }
}
